﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Tecnosop.Dominio;
using Tecnosop.WebUI.Models;
using Tecnosop.WebUI.Infrastructure.Notification;
using System.Web.UI;
using Telerik.Web.Mvc;
using System.Web.Routing;

namespace Tecnosop.WebUI.Controllers
{
    [Authorize]
    public partial class EquipoController : Controller
    {
        private Entidades db = new Entidades();

        #region CRUD

        public virtual ViewResult Index()
        {
            var equipo = db.EQUIPO.Include(e => e.TIPO_EQUIPO1);
            return View(equipo.ToList());
        }

        public virtual ViewResult Details(int id)
        {
            EQUIPO equipo = db.EQUIPO.Find(id);

            var CONS = db.CONSIGNACION_EQUIPO.Where(c => c.CODIGO_ITEM == id);
            List<EquipoEnConsignacion> consignaciones = new List<EquipoEnConsignacion>();
            foreach (var consignacion in CONS)
            {
                consignaciones.Add(new EquipoEnConsignacion
                {
                    CODIGO_ITEM = consignacion.CODIGO_ITEM,
                    CONSIGNACION = consignacion.CONSIGNACION,
                    CONSIGNACION_ORIGINAL = consignacion.CONSIGNACION,
                    NUMERO_SERIE = consignacion.NUMERO_SERIE,
                    NUMERO_SERIE_ORIGINAL = consignacion.NUMERO_SERIE
                });
            }


            return View(new EquipoYConsignacionesViewModel
            {
                CODIGO_ITEM = equipo.CODIGO_ITEM,
                MARCA = equipo.ITEM.MARCA,
                MODELO = equipo.ITEM.MODELO,
                PRECIO = equipo.ITEM.PRECIO,
                TIPO = equipo.TIPO_EQUIPO,
                OPERACION_BN = equipo.OPERACION_BN ?? false,
                OPERACION_COLOR = equipo.OPERACION_COLOR ?? false,
                Consignaciones = consignaciones//db.CONSIGNACION_EQUIPO.Where(c => c.CODIGO_ITEM == id)
            });
        }

        public virtual ActionResult Create()
        {
            ViewBag.TIPO1 = new SelectList(db.TIPO_EQUIPO, "TIPO_EQUIPO1", "TIPO_EQUIPO1");
            //ViewBag.TIPO1 = new SelectList(db.TIPO, "TIPO1", "TIPO1");
            //ViewBag.SUBTIPO1 = new SelectList(db.SUB_TIPO, "SUBTIPO", "SUBTIPO");
            return View();
        }

        [HttpPost]
        public virtual ActionResult Create(EquipoViewModel equipoVM)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    ITEM item = new ITEM
                    {
                        PRECIO = equipoVM.PRECIO,
                        MARCA = equipoVM.MARCA,
                        MODELO = equipoVM.MODELO
                    };

                    db.ITEM.Add(item);
                    db.SaveChanges();

                    EQUIPO equipo = new EQUIPO
                    {
                        CODIGO_ITEM = item.CODIGO_ITEM,
                        TIPO_EQUIPO = equipoVM.TIPO,
                        OPERACION_COLOR = equipoVM.OPERACION_COLOR,
                        OPERACION_BN = equipoVM.OPERACION_BN
                    };

                    db.EQUIPO.Add(equipo);
                    db.SaveChanges();

                    this.ShowMessage(MessageType.Success, "El equipo ID: [" + equipo.CODIGO_ITEM + "] fue agregado exitosamente.", true);
                    return RedirectToAction("Index");
                }
                catch
                {
                    this.ShowMessage(MessageType.Error, "Ocurrió un error al intentar agregar el equipo.", true);
                    ViewBag.TIPO1 = new SelectList(db.TIPO_EQUIPO, "TIPO_EQUIPO1", "TIPO_EQUIPO1");
                    return View(equipoVM);
                }
            }

            this.ShowMessage(MessageType.Warning, "Datos incorrectos, dañados o error durante su transmisión.");
            ViewBag.TIPO1 = new SelectList(db.TIPO_EQUIPO, "TIPO_EQUIPO1", "TIPO_EQUIPO1");
            return View(equipoVM);
        }

        public virtual ActionResult Edit(int id)
        {
            ViewBag.TIPO1 = new SelectList(db.TIPO_EQUIPO, "TIPO_EQUIPO1", "TIPO_EQUIPO1");

            EQUIPO equipo = db.EQUIPO.Find(id);

            EquipoViewModel equipoVM = new EquipoViewModel
            {
                MARCA = equipo.ITEM.MARCA,
                MARCA_ORIGINAL = equipo.ITEM.MARCA,
                MODELO = equipo.ITEM.MODELO,
                MODELO_ORIGINAL = equipo.ITEM.MODELO,
                PRECIO = equipo.ITEM.PRECIO,
                //SUBTIPO = equipo.ITEM.SUBTIPO,
                TIPO = equipo.TIPO_EQUIPO,
                CODIGO_ITEM = equipo.ITEM.CODIGO_ITEM,
                OPERACION_BN = equipo.OPERACION_BN ?? false,
                OPERACION_COLOR = equipo.OPERACION_COLOR ?? false
            };

            return View(equipoVM);
        }

        [HttpPost]
        public virtual ActionResult Edit(EquipoViewModel equipoVM)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    EQUIPO equipo = db.EQUIPO.Find(equipoVM.CODIGO_ITEM);

                    equipo.ITEM.MARCA = equipoVM.MARCA;
                    equipo.ITEM.MODELO = equipoVM.MODELO;
                    equipo.ITEM.PRECIO = equipoVM.PRECIO;
                    //equipo.ITEM.SUBTIPO = equipoVM.SUBTIPO;
                    equipo.TIPO_EQUIPO = equipoVM.TIPO;
                    equipo.OPERACION_BN = equipoVM.OPERACION_BN;
                    equipo.OPERACION_COLOR = equipoVM.OPERACION_COLOR;

                    db.Entry(equipo).State = EntityState.Modified;
                    db.SaveChanges();

                    this.ShowMessage(MessageType.Success, "Cambios guardados correctamente.");
                    return RedirectToAction(Actions.Details(equipoVM.CODIGO_ITEM));
                }
                catch
                {
                    this.ShowMessage(MessageType.Error, "Ocurrió un error al intentar guardar los cambios.");
                    ViewBag.TIPO1 = new SelectList(db.TIPO_INSUMO, "TIPO_INSUMO1", "TIPO_INSUMO1");
                    //ViewBag.TIPO1 = new SelectList(db.TIPO, "TIPO1", "TIPO1");
                    //ViewBag.SUBTIPO1 = new SelectList(db.SUB_TIPO, "SUBTIPO", "SUBTIPO");
                    return View(equipoVM);
                }
            }

            this.ShowMessage(MessageType.Warning, "Datos incorrectos, dañados o error durante su transmisión.");
            ViewBag.TIPO1 = new SelectList(db.TIPO_INSUMO, "TIPO_INSUMO1", "TIPO_INSUMO1");
            //ViewBag.TIPO1 = new SelectList(db.TIPO, "TIPO1", "TIPO1");
            //ViewBag.SUBTIPO1 = new SelectList(db.SUB_TIPO, "SUBTIPO", "SUBTIPO");
            return View(equipoVM);
        }

        public virtual ActionResult Delete(int id)
        {
            EQUIPO equipo = db.EQUIPO.Find(id);
            return View(new EquipoViewModel
            {
                CODIGO_ITEM = equipo.CODIGO_ITEM,
                MARCA = equipo.ITEM.MARCA,
                MODELO = equipo.ITEM.MODELO,
                PRECIO = equipo.ITEM.PRECIO,
                //SUBTIPO = equipo.ITEM.SUBTIPO,
                TIPO = equipo.TIPO_EQUIPO,
                OPERACION_BN = equipo.OPERACION_BN ?? false,
                OPERACION_COLOR = equipo.OPERACION_COLOR ?? false
            });
        }

        [HttpPost ,ActionName("Delete")]
        public virtual ActionResult DeleteConfirmed(int id)
        {
            try
            {
                EQUIPO equipo = db.EQUIPO.Find(id);

                if (equipo.CONSIGNACION_EQUIPO.Any())
                {
                    this.ShowMessage(MessageType.Error, "No se puede eliminar este equipo ya que tiene consignaciones asignadas. Elimine primero las consignaciones");
                    return RedirectToAction(Actions.Index());
                }

                db.EQUIPO.Remove(equipo);
                db.SaveChanges();

                this.ShowMessage(MessageType.Success, "El equipo fue eliminado exitosamente.");
                return RedirectToAction(Actions.Index());
            }
            catch
            {
                this.ShowMessage(MessageType.Error, "Ocurrio un error al intentar eliminar el equipo.");
                return RedirectToAction(Actions.Delete(id));
            }
        }

        #endregion

        #region Consignacion de Equipos

        public virtual ActionResult Consignaciones()
        {
            List<EquipoEnConsignacion2> listaConsignaciones = new List<EquipoEnConsignacion2>();
            foreach (var cs in db.CONSIGNACION_EQUIPO)
            {
                if (cs.EQUIPO_EN_CONVENIO != null)
                {
                    var equipoEnConvenio = db.EQUIPO_EN_CONVENIO.Where(c => cs.NUMERO_SERIE == c.NUMERO_SERIE && c.CONVENIO.CONVENIO_VIGENTE == true);
                    if (equipoEnConvenio.Count() > 0)
                    {
                        var varR = equipoEnConvenio.FirstOrDefault().NUMERO_CONVENIO;
                        EquipoEnConsignacion2 equipoC = new EquipoEnConsignacion2
                        {
                            CODIGO_ITEM = cs.CODIGO_ITEM,
                            CONSIGNACION = cs.CONSIGNACION,
                            NUMERO_SERIE = cs.NUMERO_SERIE,
                            Convenio = equipoEnConvenio.FirstOrDefault().NUMERO_CONVENIO,
                            Dirección = equipoEnConvenio.FirstOrDefault().DIRECCION_EQUIPO
                        };
                        listaConsignaciones.Add(equipoC);

                    }



                    else
                    {

                        EquipoEnConsignacion2 equipoC = new EquipoEnConsignacion2
                        {
                            CODIGO_ITEM = cs.CODIGO_ITEM,
                            CONSIGNACION = cs.CONSIGNACION,
                            NUMERO_SERIE = cs.NUMERO_SERIE,
                        };
                        listaConsignaciones.Add(equipoC);

                    }


                }
                else
                {

                    EquipoEnConsignacion2 equipoC = new EquipoEnConsignacion2
                    {
                        CODIGO_ITEM = cs.CODIGO_ITEM,
                        CONSIGNACION = cs.CONSIGNACION,
                        NUMERO_SERIE = cs.NUMERO_SERIE,
                    };
                    listaConsignaciones.Add(equipoC);

                }
            }
                
            return View(listaConsignaciones);
           //return View(db.CONSIGNACION_EQUIPO.ToList());
        }

        [HttpPost]
        public virtual ActionResult GridAddConsignacion(int id)
        {
            CONSIGNACION_EQUIPO consignacion = new CONSIGNACION_EQUIPO();
            //if (id != 0)
            consignacion.CODIGO_ITEM = id;

            if (TryUpdateModel(consignacion))
            {
                if (consignacion.CONSIGNACION == 0)
                {
                    var todos = db.CONSIGNACION_EQUIPO.Where(c => c.CONSIGNACION >= 500);//.First();

                    if (todos.Count() == 0)
                    {
                        consignacion.CONSIGNACION = 500; //POR REQUERIMIENTO DEL CLIENTE
                    }
                    else
                    {
                        var ultimo = todos.OrderByDescending(c => c.CONSIGNACION).First();
                        consignacion.CONSIGNACION = ultimo.CONSIGNACION + 1;
                    }
                }
                db.CONSIGNACION_EQUIPO.Add(consignacion);

                this.ShowMessage(MessageType.Success, "Se añadió la consignación: [" + consignacion.CONSIGNACION + "] a este equipo.");
                db.SaveChanges();
            }
            else
            {
                this.ShowMessage(MessageType.Error, "Ocurrió un error al tratar de añadir una consignación a este equipo.");
            }

            return RedirectToAction(Actions.Details(id));
        }

        [HttpPost]
        public virtual ActionResult GridEditConsignacion()
        {
            EquipoEnConsignacion consignacionVM = new EquipoEnConsignacion();

            if (TryUpdateModel(consignacionVM))
            {
                var consignacion = db.CONSIGNACION_EQUIPO.Find(consignacionVM.NUMERO_SERIE_ORIGINAL);

                if (!consignacionVM.NUMERO_SERIE.Equals(consignacionVM.NUMERO_SERIE_ORIGINAL))
                {
                    db.CONSIGNACION_EQUIPO.Remove(consignacion);
                    CONSIGNACION_EQUIPO new_consignacion = new CONSIGNACION_EQUIPO
                        {
                            CODIGO_ITEM = consignacion.CODIGO_ITEM,
                            CONSIGNACION = consignacionVM.CONSIGNACION,
                            NUMERO_SERIE = consignacionVM.NUMERO_SERIE
                        };
                    db.SaveChanges();
                    db.CONSIGNACION_EQUIPO.Add(new_consignacion);
                }
                else
                {
                    consignacion.CONSIGNACION = consignacionVM.CONSIGNACION;
                    db.Entry(consignacion).State = EntityState.Modified;
                }

                db.SaveChanges();
                this.ShowMessage(MessageType.Success, "Se editó correctamente la consignación: [" + consignacion.CONSIGNACION + "] de este equipo.");
            }
            else
            {
                this.ShowMessage(MessageType.Error, "Ocurrió un error al tratar de editar la consignación: [" + consignacionVM.CONSIGNACION ?? -1 + "] a este equipo.");
            }

            return RedirectToAction(Actions.Details(consignacionVM.CODIGO_ITEM));
        }

        [HttpPost]
        public virtual ActionResult GridDeleteConsignacion(string NUMERO_SERIE)
        {
            CONSIGNACION_EQUIPO consignacion = db.CONSIGNACION_EQUIPO.Find(NUMERO_SERIE);
            db.CONSIGNACION_EQUIPO.Remove(consignacion);
            db.SaveChanges();

            this.ShowMessage(MessageType.Success, "Se eliminó correctamente la consignación: [" + consignacion.CONSIGNACION + "].");
            return RedirectToAction(Actions.Details(consignacion.CODIGO_ITEM));
        }

        #endregion

        #region Validaciones

        [OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
        public virtual JsonResult ValidaSerieUnico(string NUMERO_SERIE_ORIGINAL, string NUMERO_SERIE)
        {
            if (NUMERO_SERIE.Equals(NUMERO_SERIE_ORIGINAL))
            {
                return Json(true, JsonRequestBehavior.AllowGet);
            }
            else
            {
                return Json(!db.CONSIGNACION_EQUIPO.Any(c => c.NUMERO_SERIE == NUMERO_SERIE), JsonRequestBehavior.AllowGet);
            }
        }

        [OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
        public virtual JsonResult ValidaConsignacionUnica(int? CONSIGNACION_ORIGINAL, int CONSIGNACION)
        {
            if (CONSIGNACION == CONSIGNACION_ORIGINAL)
            {
                return Json(true, JsonRequestBehavior.AllowGet);
            }
            else
            {
                return Json(!db.CONSIGNACION_EQUIPO.Any(c => c.CONSIGNACION == CONSIGNACION), JsonRequestBehavior.AllowGet);
            }
        }

        [OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
        public virtual JsonResult ValidaMarcaYModeloUnicos(string MARCA, string MODELO, string MARCA_ORIGINAL, string MODELO_ORIGINAL)
        {
            if (MARCA.Equals(MARCA_ORIGINAL) && MODELO.Equals(MODELO_ORIGINAL))
                return Json(true, JsonRequestBehavior.AllowGet);

            return Json(!db.ITEM.Where(i => i.MARCA == MARCA).Any(i => i.MODELO == MODELO), JsonRequestBehavior.AllowGet);
        }

        #endregion

        #region Busqueda

        [ChildActionOnly]
        public virtual ActionResult Search()
        {
            return PartialView();
        }

        public virtual ActionResult Busqueda()
        {
            return View();
        }

        public virtual ActionResult ResultadoBusqueda(string Criterios, string AreaBusqueda)
        {
            switch (Criterios)
            {
                case "Codigo":
                    int codigo;

                    this.ShowMessage(MessageType.Info, "Se muestran los resultados de: \"" + AreaBusqueda + "\" bajo el criterio de: \"" + Criterios + "\".");
                    return View(new ResultadoBusquedaEquipoViewModel
                        {
                            Resultado = Int32.TryParse(AreaBusqueda, out codigo)
                                        ? db.EQUIPO.Where(c => c.CODIGO_ITEM == codigo).ToList()
                                        : new List<EQUIPO>(),
                            CriterioParaOrdenar = Criterios
                        });
                case "Tipo":

                    this.ShowMessage(MessageType.Info, "Se muestran los resultados de: \"" + AreaBusqueda + "\" bajo el criterio de: \"" + Criterios + "\".");
                    return View(new ResultadoBusquedaEquipoViewModel
                    {
                        Resultado = db.EQUIPO.Where(c => c.TIPO_EQUIPO.Contains(AreaBusqueda)).ToList(),
                        CriterioParaOrdenar = Criterios
                    });
                case "Marca":

                    this.ShowMessage(MessageType.Info, "Se muestran los resultados de: \"" + AreaBusqueda + "\" bajo el criterio de: \"" + Criterios + "\".");
                    return View(new ResultadoBusquedaEquipoViewModel
                    {
                        Resultado = db.EQUIPO.Where(e => e.ITEM.MARCA.Contains(AreaBusqueda)).ToList(),
                        CriterioParaOrdenar = Criterios
                    });
                case "Modelo":

                    this.ShowMessage(MessageType.Info, "Se muestran los resultados de: \"" + AreaBusqueda + "\" bajo el criterio de: \"" + Criterios + "\".");
                    return View(new ResultadoBusquedaEquipoViewModel
                    {
                        Resultado = db.EQUIPO.Where(e => e.ITEM.MODELO.Contains(AreaBusqueda)).ToList(),
                        CriterioParaOrdenar = Criterios
                    });
                default:
                    return PartialView(Views.Search);
            }
        }

        #endregion

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}